package com.fau.wm.aop;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import com.fau.wm.dao.IBaseDao;
import com.fau.wm.entity.MedicalAdmin;
import com.fau.wm.entity.MedicalLogistics;
import com.fau.wm.entity.MedicalOrdersAlreadyDelivery;
import com.fau.wm.entity.MedicalOrdersLog;
import com.fau.wm.entity.MedicalOrdersProSta;
import com.fau.wm.entity.MedicalOrdersProduct;
import com.fau.wm.entity.MedicalOrdersStorage;
import com.fau.wm.entity.MedicalOrdersWaitDelivery;
import com.fau.wm.util.SystemConfig;

/**
 * @desc 产品销售量统计
 * @author dangjh
 * @datetime 2014年12月12日 下午5:23:36
 */
@Aspect
@Component
public class ProductSalesStaAop {

	@Resource
	private IBaseDao iBaseDao;
	
	/**
	 * @desc 发货切点
	 * @author dangjh
	 * @datetime 2014年12月11日 下午9:21:46
	 */
	@Pointcut("execution(* com.fau.wm.service.impl.OrdersManagerService.delivery(..))")
	private void delivery() {}
	
	/**
	 * @desc 批量发货切点
	 * @author dangjh
	 * @datetime 2014年12月11日 下午9:21:46
	 */
	@Pointcut("execution(* com.fau.wm.service.impl.OrdersManagerService.importDelivery(..))")
	private void importDelivery() {}
	
	/**
	 * @desc 退单切点
	 * @author dangjh
	 * @datetime 2014年12月11日 下午9:21:46
	 */
	@Pointcut("execution(* com.fau.wm.service.impl.OrdersManagerService.ordersRetreat(..))")
	private void ordersRetreat() {}
	
	/**
	 * @desc 批量退单切点
	 * @author dangjh
	 * @datetime 2014年12月11日 下午9:21:46
	 */
	@Pointcut("execution(* com.fau.wm.service.impl.OrdersManagerService.importRetreat(..))")
	private void importRetreat() {}
	
	/**
	 * @desc 签收切点
	 * @author dangjh
	 * @datetime 2014年12月11日 下午9:21:46
	 */
	@Pointcut("execution(* com.fau.wm.service.impl.OrdersManagerService.ordersSign(..))")
	private void ordersSign() {}
	
	/**
	 * @desc 批量签收切点
	 * @author dangjh
	 * @datetime 2014年12月11日 下午9:21:46
	 */
	@Pointcut("execution(* com.fau.wm.service.impl.OrdersManagerService.importSign(..))")
	private void importSign() {}
	
	/**
	 * @desc 修改产品销售统计状态为——已发货
	 * @param joinPoint
	 * @author dangjh
	 * @datetime 2014年12月12日 下午6:55:53
	 */
	@AfterReturning(value="delivery()", returning="retVal")
	public void delivery(JoinPoint joinPoint, String retVal) {
		Object[] obj = (Object[]) joinPoint.getArgs();
		MedicalOrdersWaitDelivery order = (MedicalOrdersWaitDelivery) obj[0];
		
		MedicalOrdersStorage ordersStorage = (MedicalOrdersStorage) this.iBaseDao.getObject(MedicalOrdersStorage.class, order.getId());
		MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		// 记录订单操作日志
		MedicalOrdersLog log = new MedicalOrdersLog();
		log.setOrderNo(ordersStorage.getSerialNum());
		log.setName(admin.getName());
		log.setUserName(admin.getUsername());
		log.setContent("订单操作  订单发货");
		log.setEid(admin.getEnterpriseId());
		this.iBaseDao.saveObject(log);
		
		if(retVal.equals("1")) {
			this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ?, m.logisticId = ? where m.orderId = ? ", SystemConfig.ORDERS_DELIVERY_TYPE, order.getExpressId(), order.getId());
			
			// 订单系统-各省订单统计（发货后为在途订单，即无反馈订单）
			this.iBaseDao.updateHql("update MedicalOrdersProvinceSta m set m.deliveryType = ? where m.ordersId = ? ", SystemConfig.ORDERS_DELIVERY_TYPE, order.getId());
		}
	}
	
	/**
	 * @desc 已发货
	 * @param joinPoint
	 * @author dangjh
	 * @datetime 2014年12月12日 下午7:04:10
	 */
	@AfterReturning("importDelivery()")
	public void importDelivery(JoinPoint joinPoint) {
		Object[] obj = joinPoint.getArgs();
		File file = (File) obj[1];
		Workbook workbook;
		// 订单序号
		List<String> numList = new ArrayList<String>();
		List<String> expressList = new ArrayList<String>();
		try {
			InputStream is = new FileInputStream(file);
			workbook = WorkbookFactory.create(is);
			is.close();
			Sheet sheet = workbook.getSheetAt(0);
			Iterator<Row> rows = sheet.rowIterator();
			Row row;
			// 循环导入
			while(rows.hasNext()){
				row = rows.next();
				if(row.getRowNum() == 0) continue;
				String ordersSerialNum = "";
				String LogisticsSerialNum = "";
				if(HSSFCell.CELL_TYPE_STRING == row.getCell(0).getCellType()) {
					ordersSerialNum = row.getCell(0).getStringCellValue().trim();
				} else {
					ordersSerialNum = String.format("%.0f",row.getCell(0).getNumericCellValue());
				}
				if(HSSFCell.CELL_TYPE_STRING == row.getCell(1).getCellType()) {
					LogisticsSerialNum = row.getCell(1).getStringCellValue().trim();
				} else {
					LogisticsSerialNum = String.format("%.0f",row.getCell(1).getNumericCellValue());
				}
				
				if(StringUtils.isNotBlank(ordersSerialNum)) {
					numList.add(ordersSerialNum);
				}
				if(StringUtils.isNotBlank(LogisticsSerialNum)) {
					expressList.add(LogisticsSerialNum);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		if(numList.size() > 0 && expressList.size() > 0) {
			this.changeProductStatusExpressIds(numList.toArray(), expressList.toArray());
		}
	}
	
	/**
	 * @desc 退单
	 * @param joinPoint
	 * @author dangjh
	 * @datetime 2014年12月12日 下午8:03:39
	 */
	@AfterReturning("ordersRetreat()")
	public void ordersRetreat(JoinPoint joinPoint) {
		Object[] obj = (Object[]) joinPoint.getArgs();
		String orderIds = (String) obj[0];
		String[] ids = orderIds.split(",");
		for(String id : ids) {
			// 财务系统-订单销售量统计
			this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", SystemConfig.ORDERS_RETREAT_TYPE, id);
			
			MedicalOrdersStorage ordersStorage = (MedicalOrdersStorage) this.iBaseDao.getObject(MedicalOrdersStorage.class, id);
			MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			// 记录订单操作日志
			MedicalOrdersLog log = new MedicalOrdersLog();
			log.setOrderNo(ordersStorage.getSerialNum());
			log.setName(admin.getName());
			log.setUserName(admin.getUsername());
			log.setContent("订单操作   订单退单");
			log.setEid(admin.getEnterpriseId());
			this.iBaseDao.saveObject(log);
			
			// 订单系统-各省订单统计
			this.iBaseDao.updateHql("update MedicalOrdersProvinceSta m set m.deliveryType = ? where m.ordersId = ? ", SystemConfig.ORDERS_RETREAT_TYPE, id);
		}
	}
	
	/**
	 * @desc 批量退单
	 * @param joinPoint
	 * @author dangjh
	 * @datetime 2014年12月12日 下午8:05:12
	 */
	@AfterReturning("importRetreat()")
	public void importRetreat(JoinPoint joinPoint) {
		Object[] obj = joinPoint.getArgs();
		File file = (File) obj[0];
		Workbook workbook;
		// 订单序号
		List<String> numList = new ArrayList<String>();
		try {
			InputStream is = new FileInputStream(file);
			workbook = WorkbookFactory.create(is);
			is.close();
			Sheet sheet = workbook.getSheetAt(0);
			Iterator<Row> rows = sheet.rowIterator();
			Row row;
			// 循环导入
			while(rows.hasNext()){
				row = rows.next();
				if(row.getRowNum() == 0) continue;
				String expressNo = "";
				if(HSSFCell.CELL_TYPE_STRING == row.getCell(0).getCellType()) {
					expressNo = row.getCell(0).getStringCellValue().trim();
				} else {
					expressNo = String.format("%.0f",row.getCell(0).getNumericCellValue());
				}
				if(StringUtils.isNotBlank(expressNo)) {
					numList.add(expressNo);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		if(numList.size() > 0) {
			this.changeProductStatus(numList.toArray(), SystemConfig.ORDERS_RETREAT_TYPE);
		}
	}
	
	/**
	 * @desc 签收
	 * @param joinPoint
	 * @author dangjh
	 * @datetime 2014年12月12日 下午8:13:38
	 */
	@AfterReturning("ordersSign()")
	public void ordersSign(JoinPoint joinPoint) {
		Object[] obj = (Object[]) joinPoint.getArgs();
		String orderIds = (String) obj[1];
		String[] ids = orderIds.split(",");
		for(String id : ids) {
			MedicalOrdersStorage ordersStorage = (MedicalOrdersStorage) this.iBaseDao.getObject(MedicalOrdersStorage.class, id);
			MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			// 记录订单操作日志
			MedicalOrdersLog log = new MedicalOrdersLog();
			log.setOrderNo(ordersStorage.getSerialNum());
			log.setName(admin.getName());
			log.setUserName(admin.getUsername());
			log.setContent("订单操作   订单签收");
			log.setEid(admin.getEnterpriseId());
			this.iBaseDao.saveObject(log);
			
			
			// 财务系统-产品销售量统计
			this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", SystemConfig.ORDERS_SIGN_TYPE, id);
			
			// 订单系统-各省订单统计
			this.iBaseDao.updateHql("update MedicalOrdersProvinceSta m set m.deliveryType = ? where m.ordersId = ? ", SystemConfig.ORDERS_SIGN_TYPE, id);
			
			//--------------------------- 订单系统-产品销售统计---------------------------
			this.saveProductSta(id, null);
		}
	}
	
	/**
	 * @desc 产品销售实体保存
	 * @author dangjh
	 * @datetime 2014年12月13日 下午6:09:39
	 */
	@SuppressWarnings("unchecked")
	private void saveProductSta(String orderId, String expressNo) {
		
		MedicalOrdersAlreadyDelivery already = null;
		if(StringUtils.isNotBlank(orderId)) {
			already = (MedicalOrdersAlreadyDelivery) this.iBaseDao.getObjectByHql("from MedicalOrdersAlreadyDelivery m where m.id = ? ", orderId);
		} else if(StringUtils.isNotBlank(expressNo)) {
			already = (MedicalOrdersAlreadyDelivery) this.iBaseDao.getObjectByHql("from MedicalOrdersAlreadyDelivery a where a.expressNo=? ", expressNo);
		}
		
		List<MedicalOrdersProduct> list = this.iBaseDao.getBySql("from MedicalOrdersProduct m where m.ordersId = ? ", null, already.getId());
		for(MedicalOrdersProduct pro : list) {
			MedicalOrdersProSta proSta = new MedicalOrdersProSta();
			proSta.setProductId(pro.getMedicine().getId());
			proSta.setProductName(pro.getMedicine().getName());
			proSta.setOrderingCount(pro.getQuantity());
			proSta.setOrderingPrice(pro.getDiscountPrice());
			proSta.setFreight(pro.getFreight());
			proSta.setOrdersTime(already.getCreateTime());
			proSta.setCusSerId(already.getCusSerId());
			proSta.setGroupId(already.getGroupId());
			proSta.setMediaId(already.getMediaId());
			proSta.setHospitalId(already.getHospitalId());
			this.iBaseDao.saveObject(proSta);
		}
	}
	
	/**
	 * @desc 批量签收
	 * @param joinPoint
	 * @author dangjh
	 * @datetime 2014年12月12日 下午8:16:12
	 */
	@AfterReturning("importSign()")
	public void importSign(JoinPoint joinPoint) {
		Object[] obj = joinPoint.getArgs();
		File file = (File) obj[0];
		Workbook workbook;
		// 订单序号
		List<String> numList = new ArrayList<String>();
		try {
			InputStream is = new FileInputStream(file);
			workbook = WorkbookFactory.create(is);
			is.close();
			Sheet sheet = workbook.getSheetAt(0);
			Iterator<Row> rows = sheet.rowIterator();
			Row row;
			// 循环导入
			while(rows.hasNext()){
				row = rows.next();
				if(row.getRowNum() == 0) continue;
				String expressNo = "";
				if(HSSFCell.CELL_TYPE_STRING == row.getCell(0).getCellType()) {
					expressNo = row.getCell(0).getStringCellValue().trim();
				} else {
					expressNo = String.format("%.0f",row.getCell(0).getNumericCellValue());
				}
				if(StringUtils.isNotBlank(expressNo)) {
					numList.add(expressNo);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(numList.size() > 0) {
			this.changeProductStatus(numList.toArray(), SystemConfig.ORDERS_SIGN_TYPE);
			for(String exNo : numList) {
				this.saveProductSta(null, exNo);
			}
		}
	}
	
	/**
	 * @desc 发货时设置财务系统产品销售统计物流公司、更新产品所在状态
	 * @param numbers
	 * @param expressIds
	 * @author dangjh
	 * 2015年1月9日 上午12:34:36
	 */
	private void changeProductStatusExpressIds(Object[] numbers, Object[] expressIds) {
		for(int i=0; i < numbers.length; i++) {
			MedicalOrdersWaitDelivery ordersWaitDelivery = (MedicalOrdersWaitDelivery) this.iBaseDao.getObjectByHql("from MedicalOrdersWaitDelivery a where a.serialNum=? ", numbers[i]);
			MedicalLogistics logistics = (MedicalLogistics) this.iBaseDao.getObjectByHql("from MedicalLogistics m where m.serialNum=? ", expressIds[i]);
			if(null != ordersWaitDelivery) {
				MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
				// 记录订单操作日志
				MedicalOrdersLog log = new MedicalOrdersLog();
				log.setOrderNo(ordersWaitDelivery.getSerialNum());
				log.setName(admin.getName());
				log.setUserName(admin.getUsername());
				log.setContent("订单操作   订单发货");
				log.setEid(admin.getEnterpriseId());
				this.iBaseDao.saveObject(log);
				// 财务系统-产品销售量统计
				this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ?, m.logisticId = ? where m.orderId = ? ", SystemConfig.ORDERS_DELIVERY_TYPE, logistics.getId(), ordersWaitDelivery.getId());
				
				// 订单系统-各省订单统计（发货后为在途订单，即无反馈订单）
				this.iBaseDao.updateHql("update MedicalOrdersProvinceSta m set m.deliveryType = ? where m.ordersId = ? ", SystemConfig.ORDERS_DELIVERY_TYPE, ordersWaitDelivery.getId());
			}
		}
	}
	
	/**
	 * @desc 修改产品状态
	 * @param ids
	 * @param status
	 * @author dangjh
	 * @datetime 2014年12月12日 下午7:58:53
	 */
	private void changeProductStatus(Object[] numbers, String status) {
		MedicalAdmin admin = (MedicalAdmin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		if(SystemConfig.ORDERS_RETREAT_TYPE.equals(status)) {
			for(Object num : numbers) {
				MedicalOrdersAlreadyDelivery ordersAlreadyDelivery = (MedicalOrdersAlreadyDelivery) this.iBaseDao.getObjectByHql("from MedicalOrdersAlreadyDelivery a where 1=1 and a.expressNo=? ", num.toString());
				if(null != ordersAlreadyDelivery) {
					// 记录订单操作日志
					MedicalOrdersLog log = new MedicalOrdersLog();
					log.setOrderNo(ordersAlreadyDelivery.getSerialNum());
					log.setName(admin.getName());
					log.setUserName(admin.getUsername());
					log.setContent("订单操作   订单退单");
					log.setEid(admin.getEnterpriseId());
					this.iBaseDao.saveObject(log);
					
					// 财务系统-产品销售量统计
					this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", status, ordersAlreadyDelivery.getId());
					
					// 订单系统-各省订单统计
					this.iBaseDao.updateHql("update MedicalOrdersProvinceSta m set m.deliveryType = ? where m.ordersId = ? ", status, ordersAlreadyDelivery.getId());
				}
			}
		} else if(SystemConfig.ORDERS_SIGN_TYPE.equals(status)) {
			for(Object num : numbers) {
				MedicalOrdersAlreadyDelivery ordersAlreadyDelivery = (MedicalOrdersAlreadyDelivery) this.iBaseDao.getObjectByHql("from MedicalOrdersAlreadyDelivery a where 1=1 and a.expressNo=? ", num.toString());
				if(null != ordersAlreadyDelivery) {
					// 记录订单操作日志
					MedicalOrdersLog log = new MedicalOrdersLog();
					log.setOrderNo(ordersAlreadyDelivery.getSerialNum());
					log.setName(admin.getName());
					log.setUserName(admin.getUsername());
					log.setContent("订单操作   订单签收");
					log.setEid(admin.getEnterpriseId());
					this.iBaseDao.saveObject(log);
					
					// 财务系统-产品销售量统计
					this.iBaseDao.updateHql("update MedicalProductStorage m set m.status = ? where m.orderId = ? ", status, ordersAlreadyDelivery.getId());
					
					// 订单系统-各省订单统计
					this.iBaseDao.updateHql("update MedicalOrdersProvinceSta m set m.deliveryType = ? where m.ordersId = ? ", status, ordersAlreadyDelivery.getId());
				}
			}
		}
	}
	
}
